#include "functionality.h"

int server;

bool reserved;
int reservedTickets[6];

void doAction();
void sendMsg(int* data);
void getMsg(int* to);
void updateUI(char* msg); // shows a certain message and refreshes the screen

int main()
    {
    int serverListener;
    struct  sockaddr_un servaddr;/* address of server */
    servaddr.sun_family = AF_UNIX;
    strcpy(servaddr.sun_path, SOCKET_PATH);

    if ((server = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        {
        perror("Client: socket");
        return 1;
        }

    if(connect(server, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
        {
        perror("Client: connect");
        return 1;
        }

    //Initialize user interface: fetch list of tickets from the server
    updateUI(NULL);
    //No tickets reserved initially
    reserved = false;
    clearArray(reservedTickets);
    /*Server listener*/
    serverListener = fork();
    if(serverListener==0)
        {
        char response[MESSAGE_STR_SIZE];
        clearArray(response);
        while(1)
            {
            }
        }
    /*Client listener*/
    while(1)
        {
        /*ACTUAL LOGIC START*/
        doAction();
        /*ACTUAL LOGIC END*/
        }
    return 1;
    }

void sendMsg(int* data)
    {
    char request[MESSAGE_STR_SIZE];
    clearArray(request);
    serialize(data, request);
    write(server, request, strlen(request));
    }

void getMsg(int* to)
    {
    char response[MESSAGE_STR_SIZE];
    clearArray(response);
    if(read(server, response, MESSAGE_STR_SIZE)>0)
        {
        deserialize(response, to);
        }
    }


void updateUI(char* msg)
    {
    int data[6];
    clearScr();
    if(msg!=NULL)
        {
        printf("-> %s", msg);
        }
    else
        {
        printf("\n");
        }
    clearArray(data);
    data[0] = LIST_GET;
    sendMsg(data);
    getMsg(data);
    if(data[0] == LIST_SEND)
        {
        //Display tickets' status as a table
        showTickets(data, reservedTickets);
        }
    else
        {
        printf("Update failed\n");
        }
    }

void doAction()
    {
    int data[6];
    char buffer[MESSAGE_STR_SIZE];
    char response[MESSAGE_STR_SIZE];
    //cleanup
    clearArray(data);
    clearArray(buffer);
    //Require further instructions
    if(!reserved)//works!!!
        {
        printf("What next?\nType:");
        printf("\t'update' to update the screen (for testing)\n");
        printf("\t'reserve' to start ticket reservation\n");
        printf("\t'exit' to stop the session\n");
        scanf("%s", buffer);
        if(strcmp( buffer, "reserve" ) == 0)
            {
            data[0] = RESERVATION_DO;
            printf("Enter the amount of tickets you want to reserve from each category \n");
            scanf("%d %d %d %d %d", &data[1], &data[2], &data[3], &data[4], &data[5]);
            copyArray(data, reservedTickets);
            sendMsg(data);
            clearArray(data);
            //sleep(1);//wait until server processes the msg
            getMsg(data);
            switch(data[0])//optimized
                {
                case RESERVATION_OK:
                    clearScr();
                    reserved = true;
                    break;
                case RESERVATION_FAIL:
                    clearScr();
                    printf("Server exception\n");
                    showTickets(data, reservedTickets);
                    break;
                default:
                    clearScr();
                    printf("Unspecified error\n");
                    showTickets(data, reservedTickets);
                }
            }
        else if(strcmp( buffer, "exit" ) == 0)
            {
            data[0] = EXIT;
            sendMsg(data);
            exit(0);
            }
        else if(strcmp( buffer, "update" ) == 0)
            {
            updateUI(NULL);
            }
        else //optimized
            {
            clearScr();
            printf("-> Unapropriate command\n");
            showTickets(data, reservedTickets);
            }
        }
    else
        {
        clearArray(buffer);
        updateUI(NULL);
        printf("\nWhat next?\nType:");
        printf("\t'unreserve' to cancel the reservation\n");
        printf("\t'reserve' to reserve more tickets\n");
        printf("\t'buy' to buy tickets\n");
        printf("\t'exit' to cancel the reservation and stop the session\n");
        scanf("%s", buffer);
        if(strcmp( buffer, "unreserve" ) == 0)
            {
            data[0] = CANCEL_DO;
            sendMsg(data);
            clearArray(data);
            //sleep(1);//wait until server processes the msg
            getMsg(data);
            switch(data[0])//optimized
                {
                case CANCEL_OK:
                    clearScr();
                    clearArray(reservedTickets);
                    updateUI("Cancelation OK.\n");
                    reserved = false;
                    break;
                case CANCEL_FAIL:
                    clearScr();
                    printf("-> Server exception\n");
                    showTickets(data, reservedTickets);
                    break;
                default:
                    clearScr();
                    printf("-> Unspecified error\n");
                    showTickets(data, reservedTickets);
                }
            }
        else if(strcmp( buffer, "buy" ) == 0)
            {
            clearArray(buffer);
            while((strcmp( buffer, "yes" ) != 0)&&(strcmp( buffer, "no" ) != 0))
                {
                printf("Are you sure? (yes or no) : ");
                scanf("%s", buffer);
                if(strcmp( buffer, "yes" ) == 0)
                    {
                    data[0] = BARGIN_DO;
                    sendMsg(data);
                    clearArray(data);
                    //sleep(1);//wait until server processes the msg
                    getMsg(data);
                    switch(data[0])//optimized
                        {
                        case BARGIN_OK:
                            clearScr();
                            updateUI("Bargin OK.\n");
                            reserved = false;
                            break;
                        case BARGIN_FAIL:
                            clearScr();
                            printf("Server exception\n");
                            showTickets(data, reservedTickets);
                            break;
                        default:
                            clearScr();
                            printf("Unspecified error\n");
                            showTickets(data, reservedTickets);
                        }
                    }
                else if(strcmp( buffer, "no" ) == 0)
                    {
                    clearScr();
                    break;
                    }
                else
                    {
                    printf("Please type 'yes' or 'no'");
                    }
                }
            }
        else if(strcmp( buffer, "reserve" ) == 0)
            {
            int temp[6]; //sum of previously reserved tickets and currently reserved ones
            data[0] = RESERVATION_DO;
            printf("Enter the amount of tickets you want to reserve additionaly from each category \n");
            scanf("%d %d %d %d %d", &data[1], &data[2], &data[3], &data[4], &data[5]);
            temp[0] = data [0];
            temp[1] = data [1] + reservedTickets[1];
            temp[2] = data [2] + reservedTickets[2];
            temp[3] = data [3] + reservedTickets[3];
            temp[4] = data [4] + reservedTickets[4];
            temp[5] = data [5] + reservedTickets[5];
            copyArray(temp, reservedTickets);
            sendMsg(data);
            clearArray(data);
            getMsg(data);
            switch(data[0])//optimized
                {
                case RESERVATION_OK:
                    clearScr();
                    reserved = true;
                    break;
                case RESERVATION_FAIL:
                    clearScr();
                    printf("Server exception\n");
                    showTickets(data, reservedTickets);
                    break;
                default:
                    clearScr();
                    printf("Unspecified error\n");
                    showTickets(data, reservedTickets);
                }
            }
        else if(strcmp( buffer, "exit" ) == 0)
            {
            data[0] = EXIT;
            sendMsg(data);
            exit(0);
            }
        else //optimized
            {
            clearScr();
            printf("-> Unapropriate command\n");
            showTickets(data, reservedTickets);
            }
        }
    }
